# -*- coding:utf-8 -*-

import os, sys
from time import sleep

class AutoIt():
    """
    Classe permettant de gérer les fenêtres Satel et MotionDevTool en arrière-plan, et de leur envoyer les messages nécessaires
    (clic bouton, remplissage de champ...)
    """
    def __init__(self):
        """
        Constructeur de la classe. S'enregistre auprès de AutoIt s'il est présent, lève une erreur sinon
        """
        # Import du client Win32 COM
        try:
            import win32com.client
        except ImportError:
            raise(ImportError, 'Ce programme requiert pywin32. Voir http://starship.python.net/crew/mhammond/win32/')
        
        import pywintypes # pour gérer les erreurs COM.
        
        # Import AutoIt
        self.autoit = None
        try:
            self.autoit = win32com.client.Dispatch("AutoItX3.Control")
            self.autoit.AutoItSetOption("WinTitleMatchMode", 4)
        except pywintypes.com_error:
            # Si on ne peut pas instancier, on essaye d'enregistrer le COM une nouvelle fois
            os.system("regsvr32 /s AutoItX3.dll")
           
        # Import AutoIT (deuxième essai si nécessaire)
        if not self.autoit:
            try:
                self.autoit = win32com.client.Dispatch("AutoItX3.Control")
            except pywintypes.com_error:
                raise(ImportError, "Impossible d'instancier le module AutoIt COM")
           
        if not self.autoit:
            print "Impossible d'instancier le module AutoIt COM"
            sys.exit(1)
     
     
    def obtenirIdentite(self):
        """
        Donne l'identité d'un utilisateur
        Retourne :
            - un tuple contenant le nom et le prénom de l'utilisateur
        """
        nom = self.autoit.ControlGetText("[CLASS:TMain]", "", "TDBEdit14").strip()
        prenom = self.autoit.ControlGetText("[CLASS:TMain]", "", "TDBEdit13").strip()
        return (nom, prenom)
     
    def __bonChamp(self, numero1, numero2, estStatique):
        """
        Méthode privée pour choisir le bon champ en fonction de l'onglet où l'on se trouve
        """
        if estStatique:
            type = "TFcaliboffls"
        else:
            type = "TFcalibofflsDyn"
        try:
            # on est dans l'onglet enregistrement
            float(self.autoit.ControlGetText("[CLASS:%s]" % type, "", "Edit1"))
        except:
            # on est dans l'un des deux autres onglets
            bonChamp = self.autoit.ControlGetText("[CLASS:%s]" % type, "", "Edit%d" % numero1)
        else:
            bonChamp = self.autoit.ControlGetText("[CLASS:%s]" % type, "", "Edit%d" % numero2)
        return bonChamp        
     
    def estPretAAcquerir(self, plateforme=True, accelerometres=True):
        """
        Spécifie si la plateforme et les capteurs sont prêts à acquérir des données
        """
        fenetreAcquisitionExiste = int(self.autoit.WinExists("[CLASS:TFcaliboffls]")) == 1 or int(self.autoit.WinExists("[CLASS:TFcalibofflsDyn]")) == 1
        acquisitionEnabled = int(self.autoit.ControlCommand("[CLASS:TFcaliboffls]", "", "[CLASS:TButton; INSTANCE:2]", "isEnabled", "")) == 1 or int(self.autoit.ControlCommand("[CLASS:TFcalibofflsDyn]", "", "[CLASS:TButton; INSTANCE:2]", "isEnabled", "")) == 1 
        startRecordingEnabled = int(self.autoit.ControlCommand("MotionDevTool", "", "[CLASS:Button; INSTANCE:24]", "isEnabled", "")) == 1
        if (fenetreAcquisitionExiste or not plateforme) and (acquisitionEnabled or not plateforme) and (startRecordingEnabled or not accelerometres):
            return True
        else:
            return False
        
    def dureeAcquisitionPlateforme(self, estStatique):
        """
        Donne la durée de l'acquisition de la plateforme. Selon l'onglet actif de la fenêtre Satel, ce n'est pas le même Edit qui est pris en compte.
        Retourne : l'entier arrondi au supérieur
        """
        bonChamp = self.__bonChamp(6, 7, estStatique)
        return int(float(bonChamp.replace(",", "."))) + (not float(bonChamp.replace(",", ".")).is_integer())
     
    def frequenceAcquisitionPlateforme(self, estStatique):
        """
        Donne la fréquence d'acquisition de la plateforme. Selon l'onglet actif de la fenêtre Satel, ce n'est pas le même Edit qui est pris en compte.
        Retourne : la fréquence sous forme d'entier
        """
        return int(self.__bonChamp(7, 8, estStatique))
     
    def lancerAcquisitionPlateforme(self, estStatique):
        """
        Lance l'acquisition des données sur la plateforme
        """
        if estStatique:
            self.autoit.ControlClick("[CLASS:TFcaliboffls]", "", "[CLASS:TButton; INSTANCE:2]")
        else:
            self.autoit.ControlClick("[CLASS:TFcalibofflsDyn]", "", "[CLASS:TButton; INSTANCE:2]")
        
    def enregistrerDonneesPlateformeDansBD(self, estStatique):
        """
            Enregistre les donnees dans la base de données
        """
        if estStatique:
            classe = "TResult"
            classe2 = "TFcaliboffls"
            instance = "2"
        else:
            classe = "TResultDyn"
            classe2 = "TFcalibofflsDyn"
            instance = "3"
        
        self.autoit.WinWait("[CLASS:%s]" % classe)
        # clic sur le bouton enregistrer
        self.autoit.ControlClick("[CLASS:%s]" % classe, "", "[CLASS:TBitBtn; INSTANCE:%s]" % instance)
        # êtes-vous sûr ?
        self.autoit.WinWait("[CLASS:TMessageForm]")
        self.autoit.ControlClick("[CLASS:TMessageForm]", "", "[CLASS:TButton; INSTANCE:2]")
        # clic sur le bouton de retour
        self.autoit.ControlClick("[CLASS:%s]" % classe2, "", "[CLASS:TBitBtn]")
        
        
    def activerTimestampAccelerometres(self):
        """
        Active l'enregistrement des timestamp et de la date de départ des accéléromètres
        """
        self.autoit.ControlSend("MotionDevTool", "", "[CLASS:Button; INSTANCE:17]", "{+}")
        self.autoit.ControlSend("MotionDevTool", "", "[CLASS:Button; INSTANCE:18]", "{+}")
        
    def activerAllSensorsAccelerometres(self):
        """
        Active l'enregistrement de l'ensemble des accéléromètres
        """
        self.autoit.ControlClick("MotionDevTool", "", "[CLASS:Button; INSTANCE:22]")
        
    
    def lancerEnregistrementAccelerometres(self):
        """
        Lance l'acquisition des données des accéléromètres
        """
        label = self.autoit.ControlGetText("MotionDevTool", "", "[CLASS:Button; INSTANCE:24]")
        if label == "Start Recording":
            self.autoit.ControlClick("MotionDevTool", "", "[CLASS:Button; INSTANCE:24]")
    
    def arreterEnregistrementAccelerometres(self):
        """
        Arrête l'acquisition des données des accéléromètres
        """
        label = self.autoit.ControlGetText("MotionDevTool", "", "[CLASS:Button; INSTANCE:24]")
        if label == "Stop Recording":
            self.autoit.ControlClick("MotionDevTool", "", "[CLASS:Button; INSTANCE:24]")
     
     
    def setCheminSortieAccelerometres(self, chemin):
        """
        Modifie le chemin où seront enregistrées les données des accéléromètres
        Arguments :
            - chemin : le chemin du dossier
        """
        if self.autoit.ControlGetText("MotionDevTool", "", "[CLASS:Edit; INSTANCE:3]") != chemin:
            self.autoit.ControlSetText("MotionDevTool", "", "[CLASS:Edit; INSTANCE:3]", chemin)
        
     
    def exporterResultats(self, chemin, nomSortieSansExtension, estStatique):
        """
        Exporte les résultats nécessaires pour la plateforme
        Arguments :
            - prefixe : un préfixe à rajouter au chemin si besoin
        Retourne :
            - un tuple contenant le chemin complet d'enregistrement des infos de la plateforme et des données
        """
        if estStatique:
            tbutton = "4"
            suffixe = "_statique.txt"
        else:
            tbutton = "5"
            suffixe = "_dynamique.txt"

        # clic sur le bouton "Exporter"
        self.autoit.ControlClick("[CLASS:TMain]", "", "[CLASS:TButton; INSTANCE:%s]" % tbutton)
        self.autoit.WinWait("[Class:TFormExport]")
        # clic sur "enregistrement sélectionné seulement"
        self.autoit.ControlClick("[CLASS:TFormExport]", "", "[CLASS:TRadioButton; INSTANCE:4]")
        # clic sur "Les données capteurs"
        self.autoit.ControlClick("[CLASS:TFormExport]", "", "[CLASS:TRadioButton; INSTANCE:2]")
        # clic "ok"
        self.autoit.ControlClick("[CLASS:TFormExport]", "", "[CLASS:TBitBtn; INSTANCE:2]")
        # on remplit le chemin et on valide
        self.autoit.WinWaitActive("[CLASS:#32770]")
        self.autoit.send(chemin + nomSortieSansExtension + suffixe + "{ENTER}")
        sleep(0.5)
        return chemin + nomSortieSansExtension + suffixe
    
    def ControleEstActif(self, titreFenetre, controle):
        """
        Précise si un controle est actif (non grisé) ou non.
        Arguments :
            - titreFenetre : le titre de la fenêtre (peut être une regexp)
            - controle : le contrôle à vérifier
        Retourne :
            - True si le controle est actif, False sinon
        """
        return self.autoit.ControlCommand(titreFenetre, "", controle, "IsEnabled", "") == "1"
    
    def estAcquisitionStatique(self):
        """
        Détermine si l'on fait une mesure statique
        """
        return "statique" in self.autoit.WinGetText("[CLASS:TMain]")
    
    def estAcquisitionDynamique(self):
        """
        Détermine si l'on fait une mesure dynamique
        """
        return "dynamique" in self.autoit.WinGetText("[CLASS:TMain]")

    def estAcquisitionStatiqueOuDynamique(self):
        """
        """
        return self.estAcquisitionDynamique() or self.estAcquisitionStatique()


if __name__ == "__main__":
    ai = AutoIt().autoit
#    print ai.WinExists("[REGEXPTITLE:.*VLC.*]")
#    ai.WinActivate("[REGEXPTITLE:.*VLC.*]")
#    print ai.ControlGetFocus("[REGEXPTITLE:.*VLC.*]")
#    print AutoIt().ControleEstActif("[REGEXPTITLE:.*statique.*]", "[CLASS:TButton; INSTANCE:2]")
#    ai.ControlSend("[REGEXPTITLE:.*VLC.*]", "", "[CLASS:QWidget; INSTANCE:4]", "s")
    print ai.ControlCommand("[REGEXPTITLE:Examen.*]", "", "[CLASS:TButton; INSTANCE:2]", "IsVisible", "")
    ai.ControlCommand("MotionDevTool", "", "[CLASS:Button; INSTANCE:24]", "IsVisible", "")
    
